package extensions.android;

import java.util.ArrayList;
import java.util.List;

import uclm.extensions.android.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class Panel extends SurfaceView implements SurfaceHolder.Callback, Runnable
{
	private ClientActivity _activity;
	Bitmap icon;
	
	private boolean _run = true;
	private Thread _drawThread = null; 
	
	public static int WIDTH = 500;
	public static int HEIGHT= 500;

	private List<Element> _elements = new ArrayList<Element>();
	
	private Paint _textPaint = new Paint();
	
	public Panel(Context context)
	{
		super(context);
		
		init((ClientActivity)context);
	}
	
	public Panel(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		
		init((ClientActivity)context);
	}
	
	public Panel(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
		
		init((ClientActivity)context);
	}
	
	private void init(Context clientActivity)
	{
		_activity = (ClientActivity)clientActivity;
		icon = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
		getHolder().addCallback(this);

		setFocusable(true);
		setFocusableInTouchMode(true);
		requestFocus(); 
		
		_textPaint.setColor(Color.WHITE);
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		
		
		if (keyCode == KeyEvent.KEYCODE_BACK)
			return false;
		
		if (event.getRepeatCount() == 0)
		{
			_activity.getClient().sendMessage(event.getDisplayLabel()+""); 
		}
			
		return true;
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		if (event.getAction() == MotionEvent.ACTION_DOWN)
			_activity.getClient().sendMessage("Toque en ["+event.getX()+", "+event.getY()+"]");
		else if (event.getAction() == MotionEvent.ACTION_MOVE)
			_activity.getClient().sendMessage("Arrastrando en ["+event.getX()+", "+event.getY()+"]");
		else
			_activity.getClient().sendMessage("Dejado de tocar en ["+event.getX()+", "+event.getY()+"]");
		
		if (event.getX() < 30)
			synchronized (_elements) {
				_elements.clear();
			}
		else
			synchronized (_elements) {
				_elements.add(new Element(getResources(), event.getX(), event.getY()));
				_elementsSize = _elements.size();
			}
		
		return true;
	}
	
	private int _elementsSize = 0;
	
	public void tick(long dt)
	{
		synchronized (_elements) {
			for (Element e : _elements)
			{
				e.tick(dt);
			}
		}
	}
	
    public void doDraw(long dt, Canvas canvas) {
        canvas.drawColor(Color.BLACK);
        
        synchronized (_elements) {
	        for (Element e : _elements)
	        	e.doDraw(canvas);
		}
        
        canvas.drawText("FPS:"+ Math.round(1000f/dt)+" Elements:"+_elementsSize, 10, 10, _textPaint);

    }

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,	int height)
	{
		WIDTH = width;
		HEIGHT = height;
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder)
	{
		if (_drawThread == null || !_drawThread.isAlive())
		{
			_drawThread = new Thread(this);
			_run = true;
			_drawThread.start();
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder)
	{
		if (_drawThread != null && _drawThread.isAlive())
		{
			_run = false;
		}			
	}

	//Draw thread
	@Override
	public void run() {
		
		Canvas canvas;
		
		long startTime = System.currentTimeMillis();
		long elapsedTime = 0;
		
		while (_run)
		{
			//Something like vsync
			canvas = getHolder().lockCanvas();
			
			if (canvas != null)
			{
				tick(elapsedTime);
				doDraw(elapsedTime, canvas);
				
				elapsedTime = System.currentTimeMillis() - startTime;
				
				getHolder().unlockCanvasAndPost(canvas);
			}
			
			startTime = System.currentTimeMillis();
		}
		
	}
	
}